package com.wh1200.mybatis.xmlless.resolver

import com.wh1200.jackson.createObjectMapper
import com.wh1200.mybatis.xmlless.config.BaseResolverTest
import com.wh1200.xmlless.test.dao.DogDAO
import com.wh1200.xmlless.test.dao.StudentDAO
import com.wh1200.xmlless.test.dao.StudentDetailDAO
import com.wh1200.xmlless.test.model.Dog
import com.wh1200.xmlless.test.model.EducationInfo
import com.wh1200.xmlless.test.model.Student
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import kotlin.reflect.jvm.javaMethod
import kotlin.test.assertEquals

/**
 *
 * @author 吴昊
 * @date 2020/6/18 9:00
 * @since 3.1.2
 * @version 1.0
 */
class QueryResolverTest2 : BaseResolverTest(StudentDetailDAO::class.java) {

  private val objectMapper = createObjectMapper()

  @Test
  @DisplayName("测试解析方法返回集合类型，并正确识别泛型")
  fun resolveReturnType() {
    val clazz = StudentDetailDAO::class.java
    val method = StudentDetailDAO::findEducation.javaMethod!!
    val javaType = TypeResolver.resolveReturnJavaType(method, clazz)
    assertEquals(
        "[collection type; class java.util.List, contains [simple type, class com.wh1200.xmlless.test.model" +
            ".EducationInfo]]", javaType.toString()
    )
    val rs = objectMapper.readValue<Any>(
        """[{
          | "school": "南京大学"
          |}]""".trimMargin(), javaType
    )
    assert(rs is List<*>)
    rs as List<*>
    assertEquals(rs.size, 1)
    assert(rs.first() is EducationInfo)
  }

  @Test
  @DisplayName("测试解析返回泛型的基类方法，可以正确识别泛型的具体类型")
  fun resolveReturnType2() {
    val modelClass = Dog::class.java
    val mapperClass = DogDAO::class.java
    val method = DogDAO::findById.javaMethod!!
    val javaType = TypeResolver.resolveReturnJavaType(method, mapperClass)
    val returnType = TypeResolver.resolveReturnMappingType(method, mapperClass)
    assertEquals(modelClass, javaType?.rawClass)
    assertEquals(modelClass, returnType)
    val fn = StudentDAO::findById.javaMethod!!
    val javaType2 = TypeResolver.resolveReturnJavaType(fn, StudentDAO::class.java)
    assertEquals(Student::class.java, javaType2?.rawClass)
  }

  @Test
  @DisplayName("测试解析返回集合类泛型的基类方法，可以正确识别泛型的具体类型")
  fun resolveReturnType4() {
    val method = DogDAO::findAll.javaMethod!!
    val mapperClass = DogDAO::class.java
    val javaType = TypeResolver.resolveReturnJavaType(method, mapperClass)
    val returnType = TypeResolver.resolveReturnMappingType(method, mapperClass)
    assertEquals(Dog::class.java, javaType?.rawClass)
    assertEquals(Dog::class.java, returnType)
  }

  @Test
  @DisplayName("解析多层嵌套的泛型")
  fun resolveType() {
    val m = StudentDetailDAO::findEducation.javaMethod!!
    assertEquals(
        "[collection type; class java.util.List, contains [simple type, class ${EducationInfo::class.java.name}]]",
        TypeResolver.resolveReturnJavaType(m, StudentDetailDAO::class.java).toString()
    )
  }

}
